package main

import (
	"database/sql"
	"errors"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
	pkgErrors "github.com/pkg/errors"
)

func main() {
	db, err := getDB("mysql", "root:123456@tcp(127.0.0.1:3306)/test")
	//db, err := getDB("mysqls", "root:123456@tcp(127.0.0.1:3306)/test")
	if err != nil {
		fmt.Printf("orgin error: %T, %v\n", pkgErrors.Cause(err), pkgErrors.Cause(err))
		fmt.Printf("stack trace: \n%+v \n", pkgErrors.Cause(err))
		return
	}
	defer db.Close()

	user, err := queryBySql(db, "select admin_id, loginname, realname, email from ms_user where admin_id = ?", "111")
	if err != nil {
		fmt.Println(err)
		return
	}
	user.ToString()
}

type User struct {
	AdminId   string
	LoginName string
	RealName  string
	Email     string
}

func (u *User) ToString() {
	fmt.Println(u.AdminId, u.LoginName, u.RealName, u.Email)
}

func getDB(dbType string, dbUrl string) (*sql.DB, error) {
	db, err := sql.Open(dbType, dbUrl)
	if err != nil {
		return nil, pkgErrors.WithMessage(err, "could not open db conection")
	}
	return db, nil
}

func queryBySql(db *sql.DB, sql string, paramter string) (*User, error) {

	resultRow, err := db.Query(sql, paramter)
	if err != nil {
		return nil, pkgErrors.WithMessagef(err, "query error!sql, %s", sql)
	}
	if resultRow.Next() {
		user := &User{}
		err = resultRow.Scan(&user.AdminId, &user.LoginName, &user.RealName, &user.Email)
		if err != nil {
			return nil, fmt.Errorf("result row set error!,user :%s, %v", user, err)
		}
		return user, err
	}
	return nil, errors.New("123")
}
